home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Moscow ML 1.31 / source code / mosml / src / compiler / Elab.sml < prev    next >
Encoding:
Text File  |  1996-07-03  |  30.4 KB  |  1,029 lines  |  [TEXT/R*ch]

  1.  
  2. open List;
  3. open Fnlib Config Mixture Const Smlexc;
  4. open Globals Location Units Asynt Asyntfn Types;
  5.  
  6. type UEnv = (string * Type) list;   (* Syntax TyVars to TypeVars *)
  7.  
  8. (* --- Warning printing --- *)
  9.  
  10. fun isFunType tau =
  11.   case normType tau of
  12.       ARROWt _ => true
  13.     |        _ => false
  14. ;
  15.  
  16. fun unitResultExpected exp tau =
  17.   if isFunType tau then
  18.     (msgIBlock 0;
  19.      errLocation (xLR exp);
  20.      errPrompt "Warning: function-type result is being discarded.";
  21.      msgEOL(); msgEOL();
  22.      msgEBlock())
  23.   else ()
  24. ;
  25. (* --- Error printing --- *)
  26.  
  27. fun typeClash tau1 tau2 =
  28. (
  29.   resetTypePrinter();
  30.   collectExplicitVars tau1;
  31.   collectExplicitVars tau2;
  32.   msgString " of type"; msgEOL();
  33.   errPrompt "  "; printNextType tau1; msgEOL();
  34.   errPrompt "cannot be made to have type"; msgEOL();
  35.   errPrompt "  "; printNextType tau2; msgEOL();
  36.   resetTypePrinter()
  37. );
  38.  
  39. fun typeClashId (ii : IdInfo) tau1 tau2 =
  40.   let val {qualid, info} = ii in
  41.     msgIBlock 0;
  42.     errLocation (#idLoc info);
  43.     errPrompt "Type clash: identifier "; msgString (showQualId qualid);
  44.     typeClash tau1 tau2;
  45.     msgEBlock();
  46.     raise Toplevel
  47.   end
  48. ;
  49.  
  50. fun unifyId ii tau1 tau2 =
  51.   unify tau1 tau2
  52.   handle Unify => typeClashId ii tau1 tau2
  53. ;
  54.  
  55. fun typeClashPat pat tau1 tau2 =
  56. (
  57.   msgIBlock 0;
  58.   errLocation (xLR pat);
  59.   errPrompt "Type clash: pattern";
  60.   typeClash tau1 tau2;
  61.   msgEBlock();
  62.   raise Toplevel
  63. );
  64.  
  65. fun unifyPat pat tau1 tau2 =
  66.   unify tau1 tau2
  67.   handle Unify => typeClashPat pat tau1 tau2
  68. ;
  69.  
  70. fun typeClashExp exp tau1 tau2 =
  71. (
  72.   msgIBlock 0;
  73.   errLocation (xLR exp);
  74.   errPrompt "Type clash: expression";
  75.   typeClash tau1 tau2;
  76.   msgEBlock();
  77.   raise Toplevel
  78. );
  79.  
  80. fun unifyExp exp tau1 tau2 =
  81.   unify tau1 tau2
  82.   handle Unify => typeClashExp exp tau1 tau2
  83. ;
  84.  
  85. fun unifyMatch mrules tau1 tau2 =
  86.   unify tau1 tau2
  87.   handle Unify =>
  88.   let val MRule(pats, exp) = hd mrules in
  89.     msgIBlock 0;
  90.     errLocation (xxLR (hd pats) exp);
  91.     errPrompt "Type clash: match rule";
  92.     typeClash tau1 tau2;
  93.     msgEBlock();
  94.     raise Toplevel
  95.   end
  96. ;
  97.  
  98. fun looksLikeInfixId (ii : IdInfo) =
  99.   case ii of
  100.       {qualid={qual="", ...}, info={withOp=false, ...}} => true
  101.     | _ => false
  102. ;
  103.  
  104. fun isPairPat (_, pat') =
  105.   case pat' of
  106.       RECpat(ref (RECrp(fs, NONE))) => isPairRow fs
  107.     | _ => false
  108. ;
  109.  
  110. fun looksLikeInfixExp (_, exp') =
  111.   case exp' of
  112.     VARexp(ref(RESve{qualid={qual="",...}, info={withOp=false,...}}))
  113.       => true
  114.   | VARexp(ref(OVLve({qualid={qual="",...}, info={withOp=false,...}}, _, _)))
  115.       => true
  116.   | _ => false
  117. ;
  118.  
  119. fun isPairExp (_, exp') =
  120.   case exp' of
  121.     RECexp(ref (RECre fs)) => isPairRow fs
  122.   | _ => false
  123. ;
  124.  
  125. fun newUnknownPair() = type_pair (newUnknown()) (newUnknown());
  126.  
  127. infix 6 U;
  128.  
  129. fun list_union [] ys = ys
  130.   | list_union (x :: xs) ys =
  131.       if member x ys then (list_union xs ys) else (x :: list_union xs ys)
  132.  
  133. fun list_subtract xs [] = xs
  134.   | list_subtract xs ys =
  135.       let fun h [] = []
  136.             | h (x :: xs) = if member x ys then (h xs) else (x :: h xs)
  137.       in h xs end
  138. ;
  139.  
  140. fun xs U ys = list_union xs ys;
  141. fun U_map f = foldR_map list_union f [];
  142.  
  143. fun unguardedExp (_, exp') =
  144.   case exp' of
  145.     SCONexp _ => []
  146.   | VARexp _ => []
  147.   | RECexp(ref (RECre fields)) =>
  148.       U_map (fn(_, e) => unguardedExp e) fields
  149.   | RECexp(ref (TUPLEre _)) => fatalError "unguardedExp"
  150.   | VECexp es =>
  151.       U_map unguardedExp es
  152.   | LETexp(dec, exp) =>
  153.       unguardedDec dec U unguardedExp exp
  154.   | PARexp exp => unguardedExp exp
  155.   | APPexp(exp1, exp2) =>
  156.       unguardedExp exp1 U unguardedExp exp2
  157.   | INFIXexp _ =>  fatalError "unguardedExp"
  158.   | TYPEDexp(exp, ty) =>
  159.       unguardedExp exp U unguardedTy ty
  160.   | ANDALSOexp(exp1, exp2) =>
  161.       unguardedExp exp1 U unguardedExp exp2
  162.   | ORELSEexp(exp1, exp2) =>
  163.       unguardedExp exp1 U unguardedExp exp2
  164.   | HANDLEexp(exp, mrules) =>
  165.       unguardedExp exp U U_map unguardedMRule mrules
  166.   | RAISEexp exp =>
  167.       unguardedExp exp
  168.   | IFexp(e0, e1, e2) =>
  169.       unguardedExp e0 U unguardedExp e1 U unguardedExp e2
  170.   | FNexp mrules =>
  171.       U_map unguardedMRule mrules
  172.   | WHILEexp(exp1, exp2) =>
  173.       unguardedExp exp1 U unguardedExp exp2
  174.   | SEQexp(exp1, exp2) =>
  175.       unguardedExp exp1 U unguardedExp exp2
  176.  
  177. and unguardedMRule (MRule(pats, exp)) =
  178.   U_map unguardedPat pats U unguardedExp exp
  179.  
  180. and unguardedPat (_, pat') =
  181.   case pat' of
  182.     SCONpat _ => []
  183.   | VARpat _ => []
  184.   | WILDCARDpat => []
  185.   | NILpat _ => []
  186.   | CONSpat(_, p) => unguardedPat p
  187.   | EXNILpat _ => []
  188.   | EXCONSpat(_,p) => unguardedPat p
  189.   | EXNAMEpat _ => fatalError "unguardedPat"
  190.   | REFpat p => unguardedPat p
  191.   | RECpat(ref (RECrp(fs, _))) =>
  192.       U_map (fn(_, p) => unguardedPat p) fs
  193.   | RECpat(ref (TUPLErp _)) => fatalError "unguardedPat"
  194.   | VECpat ps =>
  195.       U_map unguardedPat ps
  196.   | INFIXpat _ => fatalError "unguardedPat"
  197.   | PARpat pat => unguardedPat pat
  198.   | TYPEDpat(pat, ty) =>
  199.       unguardedPat pat U unguardedTy ty
  200.   | LAYEREDpat(pat1, pat2) =>
  201.       unguardedPat pat1 U unguardedPat pat2
  202.  
  203. and unguardedDec (_, dec') =
  204.   case dec' of
  205.     VALdec _ => []
  206.   | PRIM_VALdec _ => []
  207.   | FUNdec _ => fatalError "unguardedDec"
  208.   | TYPEdec tbs => []
  209.   | PRIM_TYPEdec _ => []
  210.   | DATATYPEdec _ => []
  211.   | ABSTYPEdec(_, _, dec2) =>
  212.       unguardedDec dec2
  213.   | EXCEPTIONdec ebs =>
  214.       U_map unguardedExBind ebs
  215.   | LOCALdec (dec1, dec2) =>
  216.       unguardedDec dec1 U unguardedDec dec2
  217.   | OPENdec _ => []
  218.   | EMPTYdec => []
  219.   | SEQdec (dec1, dec2) =>
  220.       unguardedDec dec1 U unguardedDec dec2
  221.   | FIXITYdec _ => []
  222.  
  223. and unguardedExBind (EXDECexbind(_, SOME ty)) = unguardedTy ty
  224.   | unguardedExBind (EXDECexbind(_, NONE)) = []
  225.   | unguardedExBind (EXEQUALexbind(_,_)) = []
  226.  
  227. and unguardedValBind (ValBind(pat, exp)) =
  228.   unguardedPat pat U unguardedExp exp
  229.  
  230. and unguardedValDec (pvbs, rvbs) =
  231.   (U_map unguardedValBind pvbs) U
  232.   (U_map unguardedValBind rvbs)
  233.  
  234. and unguardedTy (_, ty') =
  235.   case ty' of
  236.     TYVARty ii => [#id(#qualid ii)]
  237.   | RECty fs =>
  238.       U_map (fn(_, ty) => unguardedTy ty) fs
  239.   | CONty(tys, _) =>
  240.       U_map unguardedTy tys
  241.   | FNty(ty1, ty2) =>
  242.       unguardedTy ty1 U unguardedTy ty2
  243. ;
  244.  
  245. nonfix U;
  246.  
  247. fun scopedTyVars UE unguardedTyVars =
  248.   list_subtract unguardedTyVars (map fst UE)
  249. ;
  250.  
  251. fun incrUE tyvars =
  252.   map (fn tv => (tv, TypeOfTypeVar(newExplicitTypeVar tv))) tyvars
  253. ;
  254.  
  255. fun isExpansiveExp (_, exp') =
  256.   case exp' of
  257.     VARexp _ => false
  258.   | TYPEDexp(exp,_) => isExpansiveExp exp
  259.   | FNexp _ => false
  260.   | _ => true
  261. ;
  262.  
  263. fun expansiveIdsInValBind (ValBind(pat, exp)) acc =
  264.   if (isExpansiveExp exp) then (domPatAcc pat acc) else acc
  265. ;
  266.  
  267. fun closeValBindVE onTop loc (pvbs: ValBind list) VE =
  268.   let val exIds = foldR expansiveIdsInValBind [] pvbs in
  269.     mapEnv (fn id => fn t => generalization onTop loc (member id exIds) t) VE
  270.   end
  271. ;
  272.  
  273. fun lookup_TE (TE : TyEnv) (tycon : IdInfo) =
  274.   let val {qualid, info} = tycon
  275.       val {idLoc, ...} = info
  276.   in
  277.     findInfo tyEnvOfSig TE idLoc qualid
  278.     handle Subscript =>
  279.       errorMsg idLoc ("Unbound type identifier: " ^ showQualId qualid)
  280.   end;
  281.  
  282. fun lookup_VE (VE : VarEnv) (ii : IdInfo) =
  283.   let val {qualid, info} = ii
  284.       val {idLoc, ...} = info
  285.   in
  286.     specialization(findInfo varEnvOfSig VE idLoc qualid)
  287.     handle Subscript =>
  288.       fatalError "lookup_VE"
  289.   end;
  290.  
  291. fun lookup_UE (UE : UEnv) loc (ii : IdInfo) =
  292.   let val id = #id(#qualid ii) in
  293.     lookup id UE
  294.     handle Subscript => errorMsg loc ("Unbound type variable: " ^ id)
  295.   end;
  296.  
  297. fun applyTyCon TE (tycon : IdInfo) ts =
  298.   let val tyname = lookup_TE TE tycon
  299.       val arity = List.length ts
  300.   in
  301.     if #tnArity(!(#info tyname)) <> arity then
  302.       errorMsg (#idLoc (#info tycon))
  303.         ("Arity mismatch: "^showQualId (#qualid tycon))
  304.     else ();
  305.     case #tnStr(!(#info tyname)) of
  306.         NILts =>
  307.           type_con ts tyname
  308.       | TYPEts(pars, body) =>
  309.           type_subst (zip2 pars ts) body
  310.       | DATATYPEts _ =>
  311.           type_con ts tyname
  312.       | REAts _ => fatalError "applyTyCon"
  313.   end;
  314.  
  315. fun elabTy (UE : UEnv) (TE : TyEnv) (loc, ty') =
  316.   case ty' of
  317.     TYVARty ii =>
  318.       lookup_UE UE loc ii
  319.   | RECty fs =>
  320.       type_rigid_record (map_fields (elabTy UE TE) fs)
  321.   | CONty(ty_list, tycon) =>
  322.       applyTyCon TE tycon (map (elabTy UE TE) ty_list)
  323.   | FNty(ty,ty') =>
  324.       type_arrow (elabTy UE TE ty) (elabTy UE TE ty')
  325. ;
  326.  
  327. fun elabSCon (INTscon i)    = type_int
  328.   | elabSCon (CHARscon c)   = type_char
  329.   | elabSCon (REALscon r)   = type_real
  330.   | elabSCon (STRINGscon s) = type_string
  331. ;
  332.  
  333. fun elabPat (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  334.                 (pat as (_, pat')) (pat_t : Type) (PE : VarEnv) =
  335.   case pat' of
  336.     SCONpat scon =>
  337.       (unifyPat pat (elabSCon scon) pat_t; PE)
  338.   | VARpat ii =>
  339.       bindInEnv PE (#id (#qualid ii)) (trivial_scheme pat_t)
  340.   | WILDCARDpat => PE
  341.   | NILpat ii => (unifyPat pat (lookup_VE VE ii) pat_t; PE)
  342.   | CONSpat(ii, p) =>
  343.       let val id_t = lookup_VE VE ii
  344.           val p_t = newUnknown()
  345.           val res_t = newUnknown()
  346.       in
  347.         unifyId ii id_t (type_arrow p_t res_t);
  348.         if (looksLikeInfixId ii) andalso (isPairPat p) then
  349.           (unify p_t (newUnknownPair())
  350.            handle Unify =>
  351.              typeClashId ii id_t (type_arrow (newUnknownPair()) res_t))
  352.         else ();
  353.         unifyPat pat res_t pat_t;
  354.         elabPat UE VE TE p p_t PE
  355.       end
  356.   | EXNILpat ii =>
  357.       let val id_t = lookup_VE VE ii in
  358.         unifyId ii id_t type_exn;
  359.         unifyPat pat type_exn pat_t;
  360.         PE
  361.       end
  362.   | EXCONSpat(ii, p) =>
  363.       let val id_t = lookup_VE VE ii
  364.           val p_t = newUnknown()
  365.       in
  366.         unifyId ii id_t (type_arrow p_t type_exn);
  367.         if looksLikeInfixId ii andalso isPairPat p then
  368.           (unify p_t (newUnknownPair())
  369.            handle Unify =>
  370.              typeClashId ii id_t (type_arrow (newUnknownPair()) type_exn))
  371.         else ();
  372.         unifyPat pat type_exn pat_t;
  373.         elabPat UE VE TE p p_t PE
  374.       end
  375.   | EXNAMEpat _ => fatalError "elabPat"
  376.   | REFpat p =>
  377.       let val p_t = newUnknown() in
  378.         unifyPat pat (type_ref p_t) pat_t;
  379.         elabPat UE VE TE p p_t PE
  380.       end
  381.   | RECpat(ref (RECrp(fs, dots))) =>
  382.       let val ls = map fst fs
  383.           val ps = map snd fs
  384.           val ts = map (fn _ => newUnknown()) ps
  385.           val fs_t = zip2 ls ts
  386.           fun reportClash isRigid =
  387.             let val ts' = map (fn _ => newUnknown()) ps
  388.                 val fs_t' = zip2 ls ts'
  389.             in
  390.               if isRigid then
  391.                 typeClashPat pat (type_rigid_record fs_t') pat_t
  392.               else
  393.                 typeClashPat pat
  394.                   (type_flexible_record fs_t' (fresh3DotType())) pat_t
  395.             end
  396.       in
  397.         (case dots of
  398.             NONE =>     (unify (type_rigid_record fs_t) pat_t
  399.                          handle Unify => reportClash true)
  400.           | SOME rho => (unify (type_flexible_record fs_t rho) pat_t
  401.                          handle Unify => reportClash false));
  402.         foldL_zip (elabPat UE VE TE) PE ps ts
  403.       end
  404.   | RECpat(ref (TUPLErp _)) => fatalError "elabPat"
  405.   | VECpat ps =>
  406.       let val p_t = newUnknown() in
  407.         unifyPat pat (type_vector p_t) pat_t;
  408.         foldL (fn p => fn PE => elabPat UE VE TE p p_t PE) PE ps
  409.       end
  410.   | PARpat p =>
  411.       elabPat UE VE TE p pat_t PE
  412.   | INFIXpat _ => fatalError "elabPat"
  413.   | TYPEDpat(p,ty) =>
  414.       let val ty_t = elabTy UE TE ty
  415.           val PE' = elabPat UE VE TE p pat_t PE
  416.       in
  417.         unifyPat p pat_t ty_t;
  418.         PE'
  419.       end
  420.   | LAYEREDpat(p1,p2) =>
  421.       elabPat UE VE TE p2 pat_t
  422.         (elabPat UE VE TE p1 pat_t PE)
  423. ;
  424.  
  425. fun freshTyName tycon arity =
  426.   { qualid=mkGlobalName tycon,
  427.     info=ref { tnStamp=newTypeStamp(), tnArity=arity,
  428.                tnEqu=TRUEequ, tnStr=NILts }}
  429. ;
  430.  
  431. fun makeTyName tyvar_list tycon =
  432.   let val arity = List.length tyvar_list
  433.   in freshTyName tycon arity end
  434. ;
  435.  
  436. fun initialDatBindTE (dbs : DatBind list)=
  437.   foldL
  438.     (fn (tyvar_list, tycon, _) => fn env =>
  439.        let val id = #id (#qualid tycon)
  440.        in bindInEnv env id (makeTyName tyvar_list id) end)
  441.     NILenv dbs
  442. ;
  443.  
  444. fun absTE (TE : TyEnv) =
  445.   traverseEnv
  446.     (fn id => fn tyname =>
  447.        let val {info, ...} = tyname in
  448.          case #tnStr(!info) of
  449.              DATATYPEts dt =>
  450.                (setTnEqu info FALSEequ;
  451.                 setConstructors (!currentSig) dt [])
  452.            | _ => fatalError "absTE"
  453.        end)
  454.     TE
  455. ;
  456.  
  457. fun elabTypBind (TE : TyEnv) ((tyvars, tycon, ty) : TypBind) =
  458.   let val id = #id(#qualid tycon)
  459.       val pars = map (fn tyvar => #id(#qualid tyvar)) tyvars
  460.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  461.       val us = map TypeOfTypeVar vs
  462.       val UE = zip2 pars us
  463.       val t = elabTy UE TE ty
  464.       val tyname = makeTyName tyvars id
  465.   in
  466.     setTnStr (#info tyname) (TYPEts(vs, t));
  467.     (id, tyname)
  468.   end
  469. ;
  470.  
  471. fun elabTypBindList (TE : TyEnv) (tbs : TypBind list) =
  472.   foldL_map (fn (id, tyname) => fn env => bindInEnv env id tyname)
  473.             (elabTypBind TE) NILenv tbs
  474. ;
  475.  
  476. fun elabTypBindList_opt (TE : TyEnv) = fn
  477.     SOME tbs => elabTypBindList TE tbs
  478.   | NONE => NILenv
  479. ;
  480.  
  481. fun elabPrimTypBind equ ((tyvars, tycon) : TypDesc) =
  482.   let val id = #id(#qualid tycon)
  483.       val tyname = makeTyName tyvars id
  484.   in
  485.     setTnEqu (#info tyname) equ;
  486.     (id, tyname)
  487.   end;
  488.  
  489. fun elabPrimTypBindList equ (tbs : TypDesc list) =
  490.   foldL_map (fn (id, tyname) => fn env => bindInEnv env id tyname)
  491.             (elabPrimTypBind equ) NILenv tbs
  492. ;
  493.  
  494. fun closeEE EE =
  495.   mapEnv (fn excon => fn t => generalization false nilLocation true t) EE
  496. ;
  497.  
  498. fun openVE VE =
  499.   mapEnv (fn id => fn sch => TypeOfScheme sch) VE
  500. ;
  501.  
  502. fun isRecTy (loc, ty') =
  503.   case ty' of
  504.     RECty [] => false
  505.   | RECty _ => true
  506.   | _ => false
  507. ;
  508.  
  509. fun arityOfRecTy (loc, ty') =
  510.   case ty' of
  511.       RECty fs => List.length fs
  512.     | _ => fatalError "arityOfRecTy"
  513. ;
  514.  
  515. fun elabConBind (UE : UEnv) (TE : TyEnv) res_t = fn
  516.     ConBind(ii, SOME ty) =>
  517.       let val ci = getConInfo ii
  518.           val arg_t = (elabTy UE TE ty)
  519.       in
  520.         setConType ci
  521.           (generalization false nilLocation false (type_arrow arg_t res_t));
  522.         if #conSpan(!ci) <> 1 andalso isRecTy ty then
  523.           (setConArity ci (arityOfRecTy ty);
  524.            setConIsGreedy ci true)
  525.         else ();
  526.         { qualid= #qualid(!(#idKind(#info ii))), info=ci }
  527.       end
  528.   | ConBind(ii, NONE) =>
  529.       let val ci = getConInfo ii in
  530.         setConType ci (generalization false nilLocation false res_t);
  531.         { qualid= #qualid(!(#idKind(#info ii))), info=ci }
  532.       end
  533. ;
  534.  
  535. fun setEquality (TE :TyEnv) =
  536.   traverseEnv
  537.     (fn _ => fn tyname =>
  538.        let val {info, ...} = tyname in
  539.          case #tnStr(!info) of
  540.              NILts => fatalError "setEquality"
  541.            | TYPEts(_, t) =>
  542.                setTnEqu info
  543.                  (if typeViolatesEquality t then FALSEequ else TRUEequ)
  544.            | DATATYPEts _ => fatalError "setEquality"
  545.            | REAts _ => fatalError "setEquality"
  546.        end)
  547.     TE
  548. ;
  549.  
  550. val equAttrReset = ref false;
  551.  
  552. fun maximizeEquality (TE : TyEnv) =
  553. (
  554.   equAttrReset := true;
  555.   while !equAttrReset do
  556.     (equAttrReset := false;
  557.      traverseEnv
  558.        (fn _ => fn tyname =>
  559.          let val {info, ...} = tyname in
  560.            case #tnStr(!info) of
  561.                NILts => fatalError "maximizeEquality"
  562.              | TYPEts _ => fatalError "maximizeEquality"
  563.              | DATATYPEts dt =>
  564.                  (let val CE = findConstructors (!currentSig) dt in
  565.                     case #tnEqu(!info) of
  566.                         FALSEequ => ()
  567.                       | TRUEequ  =>
  568.                           if exists (fn ci => schemeViolatesEquality
  569.                                        (#conType (!(#info ci))))
  570.                                     CE
  571.                           then
  572.                             (setTnEqu info FALSEequ; equAttrReset := true)
  573.                           else ()
  574.                       | REFequ  => fatalError "maximizeEquality"
  575.                   end)
  576.              | REAts _ => fatalError "maximizeEquality"
  577.          end)
  578.        TE)
  579. );
  580.  
  581. fun setTags (cbs : ConBind list) =
  582.   let val span = List.length cbs
  583.       fun loop n = fn
  584.           [] => ()
  585.         | (ConBind(ii, _)) :: rest =>
  586.             let val {info={idLoc, ...}, ...} = ii
  587.                 val () =
  588.                   if n > maxBlockTag then
  589.                     errorMsg idLoc
  590.      ("Implementation restriction: datatype cannot declare more than "^
  591.       makestring(maxBlockTag + 1) ^" constructors.")
  592.                   else ();
  593.                 val ci = getConInfo ii
  594.             in
  595.               setConTag ci n;
  596.               setConSpan ci span;
  597.               loop (n+1) rest
  598.             end
  599.   in loop 0 cbs end
  600. ;
  601.  
  602. fun VEofCE (CE : ConEnv) =
  603.   foldR (fn cs => fn env =>
  604.            let val {qualid, info} = cs
  605.            in bindInEnv env (#id qualid) (#conType (!info)) end)
  606.         NILenv CE
  607. ;
  608.  
  609. fun cons x xs = x :: xs;
  610.  
  611. fun elabDatBind (TE:TyEnv) ((tyvars, tycon, conbind_list) : DatBind) =
  612.   let val pars = map (fn ii => #id(#qualid ii)) tyvars
  613.       val () = setTags conbind_list
  614.       val () = incrBindingLevel()
  615.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  616.       val () = decrBindingLevel()
  617.       val us = map TypeOfTypeVar vs
  618.       val UE = zip2 pars us
  619.       val tyname = lookup_TE TE tycon
  620.       val t = type_con us tyname
  621.       val CE = foldL_map cons (elabConBind UE TE t) [] conbind_list
  622.   in
  623.     setTnStr (#info tyname) (DATATYPEts (registerConstructors(rev CE)));
  624.     VEofCE CE
  625.   end
  626. ;
  627.  
  628. fun elabDatBindList (TE : TyEnv) (dbs : DatBind list) =
  629.   foldL_map (fn env' => fn env => plusEnv env env')
  630.             (elabDatBind TE) NILenv dbs
  631. ;
  632.  
  633. fun elabExBind (UE : UEnv) (VE : VarEnv) (TE : TyEnv) = fn
  634.     EXDECexbind(ii, SOME ty) =>
  635.       let val ei = getExConInfo ii
  636.           val arg_t = (elabTy UE TE ty)
  637.       in
  638.         if typeIsImperative arg_t then ()
  639.         else errorMsg (xLR ty) "Non-imperative exception type";
  640.         if isExConStatic ei andalso isRecTy ty then
  641.           (setExConArity ei (arityOfRecTy ty);
  642.            setExConIsGreedy ei true)
  643.         else ();
  644.         (#id(#qualid ii), type_arrow arg_t type_exn)
  645.       end
  646.   | EXDECexbind(ii, NONE) =>
  647.       (#id(#qualid ii), type_exn)
  648.   | EXEQUALexbind(ii, ii') =>
  649.       (#id(#qualid ii), lookup_VE VE ii')
  650. ;
  651.  
  652. fun elabExBindList (UE : UEnv) (VE : VarEnv) (TE : TyEnv) ebs =
  653.   closeEE (foldL_map (fn (id, tau) => fn env => bindInEnv env id tau)
  654.                      (elabExBind UE VE TE) NILenv ebs)
  655. ;
  656.  
  657. (* OVL1TXXo is not a true overloaded type, *)
  658. (* because it needn't be resolved to `int', `real', or `string'. *)
  659. (* This is only a hack to catch the type inferred by the *)
  660. (* type-checker... Thus the attribute `overloaded' mustn't be *)
  661. (* turned on in the type variable. *)
  662. (* The same is true of OVL1TPUo. *)
  663.  
  664. fun elabOvlExp t ovltype =
  665.   case ovltype of
  666.       REGULARo =>
  667.         fatalError "elabOvlExp"
  668.     | OVL1NNo =>
  669.         (setCurrentBindingLevel true t;
  670.          type_arrow t t)
  671.     | OVL1NSo =>
  672.         (setCurrentBindingLevel true t;
  673.          type_arrow t type_string)
  674.     | OVL2NNBo =>
  675.         (setCurrentBindingLevel true t;
  676.          type_arrow (type_pair t t) type_bool)
  677.     | OVL2NNNo =>
  678.         (setCurrentBindingLevel true t;
  679.          type_arrow (type_pair t t) t)
  680.     | OVL1TXXo =>
  681.         (setCurrentBindingLevel false t;
  682.          type_arrow t t)
  683.     | OVL1TPUo =>
  684.         (setCurrentBindingLevel false t;
  685.          type_arrow
  686.            (type_arrow type_ppstream (type_arrow t type_unit))
  687.            type_unit)
  688. ;
  689.  
  690. fun elabExp (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  691.                  (exp as (_, exp')) exp_t =
  692.   case exp' of
  693.     SCONexp scon =>
  694.       unifyExp exp (elabSCon scon) exp_t
  695.   | VARexp(ref (RESve ii)) =>
  696.       unifyExp exp (lookup_VE VE ii) exp_t
  697.   | VARexp(ref (OVLve(_, ovltype, tau))) =>
  698.       unifyExp exp (elabOvlExp tau ovltype) exp_t
  699.   | FNexp mrules =>
  700.       elabMatch UE VE TE mrules exp_t
  701.   | APPexp(func, arg) =>
  702.       let val func_t = newUnknown()
  703.           val () = elabExp UE VE TE func func_t
  704.           val arg_t = newUnknown()
  705.           val res_t = newUnknown()
  706.       in
  707.         unifyExp func func_t (type_arrow arg_t res_t);
  708.         if looksLikeInfixExp func andalso isPairExp arg then
  709.           (unify arg_t (newUnknownPair())
  710.            handle Unify =>
  711.              typeClashExp func func_t (type_arrow (newUnknownPair()) res_t))
  712.         else ();
  713.         unifyExp exp res_t exp_t;
  714.         elabExp UE VE TE arg arg_t
  715.       end
  716.   | LETexp(dec, body) =>
  717.       let val (VE', TE') = elabDec UE VE TE false dec
  718.       in elabExp UE (plusEnv VE VE') (plusEnv TE TE') body exp_t end
  719.   | RECexp(ref (RECre fs)) =>
  720.       let val ls = map fst fs
  721.           val es = map snd fs
  722.           val ts = map (fn _ => newUnknown()) es
  723.           val fs_t = zip2 ls ts
  724.       in
  725.         (unify (type_rigid_record fs_t) exp_t
  726.          handle Unify =>
  727.            let val ts' = map (fn _ => newUnknown()) es
  728.                val fs_t' = zip2 ls ts'
  729.            in typeClashExp exp (type_rigid_record fs_t') exp_t end);
  730.         app2 (elabExp UE VE TE) es ts
  731.       end
  732.   | RECexp(ref (TUPLEre _)) => fatalError "elabExp"
  733.   | VECexp es =>
  734.       let val e_t = newUnknown() in
  735.         app (fn e => elabExp UE VE TE e e_t) es;
  736.         unifyExp exp (type_vector e_t) exp_t
  737.       end
  738.   | PARexp e =>
  739.       elabExp UE VE TE e exp_t
  740.   | INFIXexp _ => fatalError "elabExp: unresolved infix exp"
  741.   | TYPEDexp(e,ty) =>
  742.       let val ty_t = elabTy UE TE ty in
  743.         elabExp UE VE TE e exp_t;
  744.         unifyExp e exp_t ty_t
  745.       end
  746.   | ANDALSOexp(e1, e2) =>
  747.       (elabExp UE VE TE e1 type_bool;
  748.        elabExp UE VE TE e2 type_bool;
  749.        unifyExp exp type_bool exp_t)
  750.   | ORELSEexp(e1, e2) =>
  751.       (elabExp UE VE TE e1 type_bool;
  752.        elabExp UE VE TE e2 type_bool;
  753.        unifyExp exp type_bool exp_t)
  754.   | HANDLEexp(e, mrules) =>
  755.       (elabExp UE VE TE e exp_t;
  756.        elabMatch UE VE TE mrules (type_arrow type_exn exp_t))
  757.   | RAISEexp e =>
  758.       elabExp UE VE TE e type_exn
  759.   | IFexp(e0, e1, e2) =>
  760.       (elabExp UE VE TE e0 type_bool;
  761.        elabExp UE VE TE e1 exp_t;
  762.        elabExp UE VE TE e2 exp_t)
  763.   | WHILEexp(e1, e2) =>
  764.       let val e2_t = newUnknown() in
  765.         elabExp UE VE TE e1 type_bool;
  766.         elabExp UE VE TE e2 e2_t;
  767.         unitResultExpected e2 e2_t;
  768.         unifyExp exp type_unit exp_t
  769.       end
  770.   | SEQexp(e1, e2) =>
  771.       let val e1_t = newUnknown() in
  772.         elabExp UE VE TE e1 e1_t;
  773.         unitResultExpected e1 e1_t;
  774.         elabExp UE VE TE e2 exp_t
  775.       end
  776.  
  777. and elabExpSeq UE VE TE es ts =
  778.   let fun loop [] [] = ()
  779.         | loop (e :: es) (t :: ts) =
  780.             (elabExp UE VE TE e t; loop es ts)
  781.         | loop _ _ = fatalError "elabExpSeq"
  782.   in loop es ts end
  783.  
  784. and elabMatch UE VE TE mrules match_t =
  785.   let val MRule(pats1,_) = hd mrules
  786.       val arg_ts = map (fn pat => newUnknown()) pats1
  787.       val res_t = newUnknown()
  788.   in
  789.     unifyMatch mrules (foldR type_arrow res_t arg_ts) match_t;
  790.     app (fn MRule(pats, exp) => elabMRule UE VE TE exp res_t pats arg_ts)
  791.             mrules
  792.   end
  793.  
  794. and elabMRule UE VE TE exp res_t pats arg_ts =
  795.   case (pats, arg_ts) of
  796.       ([], []) => elabExp UE VE TE exp res_t
  797.     | (pat :: pats', arg_t :: arg_ts') =>
  798.         let val VE' = elabPat UE VE TE pat arg_t VE
  799.         in elabMRule UE VE' TE exp res_t pats' arg_ts' end
  800.     | (_, _) => fatalError "elabMRule"
  801.  
  802. and elabDec (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  803.             (onTop : bool) (loc, dec') =
  804.   case dec' of
  805.     VALdec (pvbs, rvbs) =>
  806.       let val tyvars = scopedTyVars UE (unguardedValDec (pvbs, rvbs))
  807.           val ()   = incrBindingLevel()
  808.           val UE'  = (incrUE tyvars) @ UE
  809.           val VE'  = elabValBind UE' VE TE pvbs
  810.           val VE'' = elabRecValBind UE' VE TE rvbs
  811.       in
  812.         decrBindingLevel();
  813.         (closeValBindVE onTop loc pvbs (plusEnv VE' VE''), NILenv)
  814.       end
  815.   | PRIM_VALdec pbs =>
  816.       let val VE' = foldL_map (fn(id, sc) => fn acc => bindInEnv acc id sc)
  817.                               (elabPrimValBind TE)
  818.                               NILenv pbs
  819.       in (VE', NILenv) end
  820.   | FUNdec _ => fatalError "elabDec"
  821.   | TYPEdec tbs =>
  822.       let val tbsTE = elabTypBindList TE tbs in
  823.         setEquality tbsTE;
  824.         (NILenv, tbsTE)
  825.       end
  826.   | PRIM_TYPEdec(equ, tbs) =>
  827.       (NILenv, elabPrimTypBindList equ tbs)
  828.   | DATATYPEdec(dbs, tbs_opt) =>
  829.       let val dbsTE = initialDatBindTE dbs
  830.           val tbsTE = elabTypBindList_opt (plusEnv TE dbsTE) tbs_opt
  831.           (* Here dbsTE will get destructively updated too. *)
  832.           val CE = elabDatBindList (plusEnv (plusEnv TE dbsTE) tbsTE) dbs
  833.       in
  834.         maximizeEquality dbsTE;
  835.         setEquality tbsTE;
  836.         (CE, plusEnv dbsTE tbsTE)
  837.       end
  838.   | ABSTYPEdec(dbs, tbs_opt, dec2) =>
  839.       let val dbsTE = initialDatBindTE dbs
  840.           val tbsTE = elabTypBindList_opt (plusEnv TE dbsTE) tbs_opt
  841.           (* Here dbsTE will get destructively updated too. *)
  842.           val CE = elabDatBindList (plusEnv (plusEnv TE dbsTE) tbsTE) dbs
  843.           val () = maximizeEquality dbsTE
  844.           val () = setEquality tbsTE
  845.           val (VE2, TE2) =
  846.             elabDec UE (plusEnv VE CE)
  847.                     (plusEnv (plusEnv TE dbsTE) tbsTE) onTop dec2
  848.       in
  849.         (* Now let's destructively update the equality attributes *)
  850.         (* and the lists of constructors! *)
  851.         (* Here VE2 and TE2 will be implicitly influenced too. *)
  852.         absTE dbsTE;
  853.         setEquality tbsTE;
  854.         (VE2, plusEnv(plusEnv dbsTE tbsTE) TE2)
  855.       end
  856.   | EXCEPTIONdec ebs =>
  857.       (elabExBindList UE VE TE ebs, NILenv)
  858.   | LOCALdec (dec1, dec2) =>
  859.       let val (VE', TE')  = elabDec UE VE TE false dec1
  860.           val (VE'',TE'') =
  861.             elabDec UE (plusEnv VE VE') (plusEnv TE TE') onTop dec2
  862.       in (VE'', TE'') end
  863.   | OPENdec ids =>
  864.       let val VE' =
  865.             foldL (fn id => fn acc =>
  866.                      bindTopInEnv acc (#uVarEnv (findSig loc id)))
  867.                   NILenv ids
  868.               val TE' =
  869.             foldL (fn id => fn acc =>
  870.                      bindTopInEnv acc (#uTyEnv (findSig loc id)))
  871.                   NILenv ids
  872.       in (VE', TE') end
  873.   | EMPTYdec => (NILenv, NILenv)
  874.   | SEQdec (dec1, dec2) =>
  875.       let val (VE', TE')  =
  876.             elabDec UE VE TE onTop dec1
  877.           val (VE'',TE'') =
  878.             elabDec UE (plusEnv VE VE') (plusEnv TE TE') onTop dec2
  879.       in (plusEnv VE' VE'', plusEnv TE' TE'') end
  880.   | FIXITYdec _ => (NILenv, NILenv)
  881.  
  882. and elabValBind (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  883.                 (vbs : ValBind list) =
  884.   let val ps = map (fn ValBind(p,e) => p) vbs
  885.       val es = map (fn ValBind(p,e) => e) vbs
  886.       val pts = map (fn _ => newUnknown()) ps
  887.       val VE' = foldL_zip (elabPat UE VE TE) NILenv ps pts
  888.   in
  889.     app2 (elabExp UE VE TE) es pts;
  890.     openVE VE'
  891.   end
  892.  
  893. and elabRecValBind (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  894.                    (vbs : ValBind list) =
  895.   let val ps = map (fn ValBind(p,e) => p) vbs
  896.       val es = map (fn ValBind(p,e) => e) vbs
  897.       val pts = map (fn _ => newUnknown()) ps
  898.       val VE' = foldL_zip (elabPat UE VE TE) NILenv ps pts
  899.       val rec_VE = plusEnv VE VE'
  900.   in
  901.     app2 (elabExp UE rec_VE TE) es pts;
  902.     openVE VE'
  903.   end
  904.  
  905. and elabPrimValBind TE (ii, ty, _, _) =
  906.   let val tyvars = varsOfTy ty
  907.       val pars = map (fn tyvar => #id(#qualid tyvar)) tyvars
  908.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  909.       val us = map TypeOfTypeVar vs
  910.       val UE = zip2 pars us
  911.       val ty_t = elabTy UE TE ty
  912.   in (#id(#qualid ii), mkScheme vs ty_t) end
  913. ;
  914.  
  915. fun elabToplevelDec (dec : Dec) =
  916. (
  917.   if unguardedDec dec <> [] then
  918.     errorMsg (xLR dec) "Unguarded type variables at the top-level"
  919.   else ();
  920.   resetBindingLevel();
  921.   elabDec [] (mkGlobalVE()) (mkGlobalTE()) true dec
  922. );
  923.  
  924.  
  925. (* --- Signatures --- *)
  926.  
  927. fun unguardedExDesc (_, SOME ty) = unguardedTy ty
  928.   | unguardedExDesc (_, NONE) = []
  929. ;
  930.  
  931. fun elabValDesc (TE : TyEnv) ((ii, ty) : ValDesc) =
  932.   let val tyvars = varsOfTy ty
  933.       val pars = map (fn tyvar => #id(#qualid tyvar)) tyvars
  934.       val vs = map (fn tv => newExplicitTypeVar tv) pars
  935.       val us = map TypeOfTypeVar vs
  936.       val UE = zip2 pars us
  937.       val ty_t = elabTy UE TE ty
  938.   in (#id(#qualid ii), mkScheme vs ty_t) end
  939. ;
  940.  
  941. fun elabExDesc (UE : UEnv) (VE : VarEnv) (TE : TyEnv)
  942.                ((ii, ty_opt) : ExDesc) =
  943.   let val {qualid={id, ...}, ...} = ii
  944.   in
  945.     case ty_opt of
  946.       SOME ty =>
  947.         let val ei = getExConInfo ii
  948.             val arg_t = (elabTy UE TE ty)
  949.         in
  950.           if typeIsImperative arg_t then ()
  951.           else errorMsg (xLR ty) "Non-imperative exception type";
  952.           if isExConStatic ei andalso isRecTy ty then
  953.             (setExConArity ei (arityOfRecTy ty);
  954.              setExConIsGreedy ei true)
  955.           else ();
  956.           (id, type_arrow arg_t type_exn)
  957.         end
  958.     | NONE =>
  959.         (id, type_exn)
  960.   end;
  961.  
  962. fun elabExDescList (UE : UEnv) (VE : VarEnv) (TE : TyEnv) eds =
  963.   closeEE (foldL_map (fn (id, tau) => fn env => bindInEnv env id tau)
  964.                      (elabExDesc UE VE TE) NILenv eds)
  965. ;
  966.  
  967. fun elabSpec (VE : VarEnv) (TE : TyEnv) (loc, spec') =
  968.   case spec' of
  969.     VALspec vds =>
  970.       let val VE' = foldL_map (fn(id, sc) => fn acc => bindInEnv acc id sc)
  971.                               (elabValDesc TE)
  972.                               NILenv vds
  973.       in (VE', NILenv) end
  974.   | PRIM_VALspec pvs =>
  975.       let val VE' = foldL_map (fn(id, sc) => fn acc => bindInEnv acc id sc)
  976.                               (elabPrimValBind TE)
  977.                               NILenv pvs
  978.       in (VE', NILenv) end
  979.   | TYPEDESCspec(equ, tds) =>
  980.       (NILenv, elabPrimTypBindList equ tds)
  981.   | TYPEspec tbs =>
  982.       let val tbsTE = elabTypBindList TE tbs in
  983.         setEquality tbsTE;
  984.         (NILenv, tbsTE)
  985.       end
  986.   | DATATYPEspec(dbs, tbs_opt) =>
  987.       let val dbsTE = initialDatBindTE dbs
  988.           val tbsTE = elabTypBindList_opt (plusEnv TE dbsTE) tbs_opt
  989.           (* Here dbsTE will get destructively updated too. *)
  990.           val CE = elabDatBindList (plusEnv (plusEnv TE dbsTE) tbsTE) dbs
  991.       in
  992.         maximizeEquality dbsTE;
  993.         setEquality tbsTE;
  994.         (CE, plusEnv dbsTE tbsTE)
  995.       end
  996.   | EXCEPTIONspec eds =>
  997.       (if U_map unguardedExDesc eds <> [] then
  998.          errorMsg loc "Type variables in an exception description"
  999.        else ();
  1000.        (elabExDescList [] VE TE eds, NILenv))
  1001.   | LOCALspec (spec1, spec2) =>
  1002.       let val (VE', TE')  = elabSpec VE TE spec1
  1003.           val (VE'',TE'') =
  1004.             elabSpec (plusEnv VE VE') (plusEnv TE TE') spec2
  1005.       in (VE'', TE'') end
  1006.   | OPENspec ids =>
  1007.       let val VE' =
  1008.             foldL (fn id => fn acc =>
  1009.                      bindTopInEnv acc (#uVarEnv (findSig loc id)))
  1010.                   NILenv ids
  1011.               val TE' =
  1012.             foldL (fn id => fn acc =>
  1013.                      bindTopInEnv acc (#uTyEnv (findSig loc id)))
  1014.                   NILenv ids
  1015.       in (VE', TE') end
  1016.   | EMPTYspec => (NILenv, NILenv)
  1017.   | SEQspec (spec1, spec2) =>
  1018.       let val (VE', TE')  = elabSpec VE TE spec1
  1019.           val (VE'',TE'') =
  1020.             elabSpec (plusEnv VE VE') (plusEnv TE TE') spec2
  1021.       in (plusEnv VE' VE'', plusEnv TE' TE'') end
  1022. ;
  1023.  
  1024. fun elabToplevelSpec (spec : Spec) =
  1025. (
  1026.   resetBindingLevel();
  1027.   elabSpec (mkGlobalVE()) (mkGlobalTE()) spec
  1028. );
  1029.